import os
from ctypes import cdll, byref, string_at, c_void_p, CFUNCTYPE, c_char_p, c_uint64, c_int64
import pyaudio
from loguru import logger
import pyttsx3
import speech_recognition as sr
import compere_final
from datetime import datetime, timedelta
import time
from wxauto import *
import re
import db
# 唤醒成功后打印的日志
def py_ivw_callback(sessionID, msg, param1, param2, info, userDate):
    # typedef int( *ivw_ntf_handler)( const char *sessionID, int msg, int param1, int param2, const void *info, void *userData );
    # 在此处编辑唤醒后的动作
    print("sessionID =>", sessionID)
    print("msg =>", msg)
    print("param1 =>", param1)
    print("param2 =>", param2)
    print("info =>", info)
    print("userDate =>", userDate)
    
    print('#######')
    obj = compere_final.ConferenceHost()
    
    print(obj.get_topic())
    print('我在')
    
    # obj.speak('你有什么吩咐') #会堵塞线程，先放着
    
    # 语音转文字
    command = speech_to_text()
    print("等待命令")
    
    
    # wav_filename = obj.tmp_audio_record(6)
    # command = obj.recognizer_by_baidu(wav_filename)
    print(f"输入的命令：{command}")
    # 命令转执行
    command_to_operate(command)
    
    
    # if "打开" in command:
    #     obj.speak("暂不支持该功能")        
    # elif "傻逼" in command:
    #     obj.speak('你才是呢，哼哼哼')
    
    # elif "关闭会议系统" in command:
    #     print('d')
    #     # 假设已经有了 MyClass 的实例 obj
    #     # obj = compere_final.ConferenceHost()
    #     obj.set_flag(False)  # 通过调用定义的方法来修改值
    # elif "现在几点" in command:
    #     now = datetime.now()
    #     current_time = now.strftime("%y-%m-%d %H:%M:%S")
    #     obj.speak(f"现在时间是{current_time}")
    # elif "今天几号" in command:
    #     obj.speak(f"今天是{datetime.now().strftime('%Y-%m-%d')}")
    # elif "黄星是谁" in command:
    #     obj.speak("黄星是我爹，你找他干嘛呀")
        
    # elif "黄兴是谁" in command:
    #     obj.speak("黄星是我爹，你找他干嘛呀")
        
    # elif "魏大师是谁" in command:
    #     obj.speak("创新发展部的老大，真名叫魏良晨，江湖人称魏大师")
    
    # elif "张辉是谁" in command:
    #     obj.speak("运营商事业部的BOSS，大家都尊称他为博士")
    
    
    
    # elif "发给" in command:
        
    #     obj.speak('好的，正在处理操作')
        
    #     ai_response = obj.send_to_ai(command)
        
    #     to_who = after_target_text(command,"发给")
        
    #     res = send_wx(to_who,ai_response)
        
    #     if res is True:    
    #         obj.speak("发送成功")
    #     else:
    #         obj.speak('发送失败')
    
    # elif "过来一下" in command:
    #     obj.speak('好的，正在处理操作')
        
    #     to_who = extract_name(command)
        
    #     send_msg = "来我的办公室"
        
    #     res = send_wx(to_who,send_msg)
    #     if res is True:    
    #         obj.speak("发送成功")
    #     else:
    #         obj.speak('发送失败')
    # else:
    #     obj.speak('好的，请稍等')
    #     command += ",请简短的回答"
    #     ai_response = obj.send_to_ai(command)
    #     print(ai_response)
    #     obj.speak(ai_response)
    
    
    
CALLBACKFUNC = CFUNCTYPE(None, c_char_p, c_uint64,
                         c_uint64, c_uint64, c_void_p, c_void_p)
pCallbackFunc = CALLBACKFUNC(py_ivw_callback)


def speak(text):
        
    try:
        # 语音识别  
        engine = pyttsx3.init()
        engine.say(text)
        
        # 存储所有要播放的文本，然后一次性播放
        # if self.flag < 1:
        engine.runAndWait()
        engine.stop()
    except Exception as e:
        print(f"speak 方法异常: {e}")
# 命令转执行
def command_to_operate(command):
    print('command_to_operate')
    try:
        dbconn = db.db()
        sql = """
            select * from bd_ai_metting_command where state = 1;
        """
        
        res_sql = dbconn.select_all(sql)['data']
        
        if res_sql:
            for res_sql_i in res_sql:
                if res_sql_i['keywords'] in command:
                    # 使用定义好的函数 进行处理
                    print(res_sql_i['keywords'])
                    func_name = res_sql_i['call_func']
                    print(func_name)
                    
                    # 使用globals()来获取函数对象
                    func = globals().get(func_name)
                    
                    if func is not None and callable(func):
                        func(command)
                        break
            else:
                print('没有匹配的命令')
        else:
            print('数据库无命令')
    except Exception as e:
        print(e)


# 会议总结
def metting_summary():
    print('metting_summary')
    obj = compere_final.ConferenceHost()
    obj.metting_summary()



# def test(command):
#     print('test')






# 实时语音转文字
def speech_to_text():
    print('语音转文字中...')
    recognizer = sr.Recognizer()
    with sr.Microphone() as source:
        print("请说话...")
        audio = recognizer.listen(source)
    try:
        text = recognizer.recognize_google(audio, language='zh-CN')  # 设置语言为中文简体
        print(f"你说的是：{text}")
        return text
    except sr.UnknownValueError:
        print("无法识别你的语音，请重试。")
        return None
    except sr.RequestError as e:
        print(f"请求出错；{e}")
        return None


# 获取名字
def extract_name(text):
    match = re.search(r'叫\s*([\w]+)\s*过来一下', text)
    if match:
        return match.group(1)
    else:
        return None


def after_target_text(text,target_word):
    
    try:
        # 获取指定文字之后的内容
        after_target = text[text.find(target_word) + len(target_word):]
        
        return after_target
    except Exception as e:
        print(f"after_target_text 方法异常: {e}")
        return None


# 发送微信
def send_wx(who,send_msg):
    
    try:
        # who = '文件传输助手'  # 指定发送对象
        # send_msg = '筱筱路可'  # 发送消息内容

        # 获取当前微信客户端
        wx = WeChat()  
        # 向某人发送消息（以文件传输助手为例）
        wx.ChatWith(who)  # 打开文件传输助手聊天窗口
        wx.SendMsg(send_msg)  # 向文件传输助手发送消息 
        return True
    except Exception as e:
        print(f"send_wx 方法异常: {e}")
        return False

 
def ivw_wakeup():
    try:
        msc_load_library = r'.\xf\bin\msc_x64.dll'
        app_id = '13023f7f'  # 填写自己的app_id
        ivw_threshold = '0:1450'
        jet_path = os.getcwd() + r'.\xf\bin\msc\res\ivw\wakeupresource.jet'
        work_dir = 'fo|' + jet_path
    except Exception as e:
        return e
 
    # ret 成功码
    MSP_SUCCESS = 0
 
    dll = cdll.LoadLibrary(msc_load_library)
    errorCode = c_int64()
    sessionID = c_void_p()
    # MSPLogin
    Login_params = "appid={},engine_start=ivw".format(app_id)
    Login_params = bytes(Login_params, encoding="utf8")
    ret = dll.MSPLogin(None, None, Login_params)
    if MSP_SUCCESS != ret:
        logger.info("MSPLogin failed, error code is: %d", ret)
        return
 
    # QIVWSessionBegin
    Begin_params = "sst=wakeup,ivw_threshold={},ivw_res_path={}".format(
        ivw_threshold, work_dir)
    Begin_params = bytes(Begin_params, encoding="utf8")
    dll.QIVWSessionBegin.restype = c_char_p
    sessionID = dll.QIVWSessionBegin(None, Begin_params, byref(errorCode))
    if MSP_SUCCESS != errorCode.value:
        logger.info("QIVWSessionBegin failed, error code is: {}".format(
            errorCode.value))
        return
 
    # QIVWRegisterNotify
    dll.QIVWRegisterNotify.argtypes = [c_char_p, c_void_p, c_void_p]
    ret = dll.QIVWRegisterNotify(sessionID, pCallbackFunc, None)
    if MSP_SUCCESS != ret:
        logger.info("QIVWRegisterNotify failed, error code is: {}".format(ret))
        return
 
    # QIVWAudioWrite
    # 创建PyAudio对象
    pa = pyaudio.PyAudio()
 
    # 设置音频参数
    sample_rate = 16000
    chunk_size = 1024
    format = pyaudio.paInt16
    channels = 1
    
    # 打开音频流
    stream = pa.open(format=format,
                     channels=channels,
                     rate=sample_rate,
                     input=True,
                     frames_per_buffer=chunk_size)
 
    # 开始录制音频
    logger.info("* start recording")
    ret = MSP_SUCCESS
    while ret == MSP_SUCCESS:  # 这里会一直进行监听你的唤醒，只要监听到你的唤醒就调用上面的py_ivw_callback函数打印日志
        audio_data = stream.read(chunk_size)
        audio_len = len(audio_data)
        ret = dll.QIVWAudioWrite(sessionID, audio_data, audio_len, 2)
    logger.info('QIVWAudioWrite ret =>{}', ret)
    logger.info("* done recording")
 
    # 关闭音频流
    stream.stop_stream()
    stream.close()
 
    # 终止PyAudio对象
    pa.terminate()
 
 
if __name__ == '__main__':
    ivw_wakeup()